﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using SimpleMap.Binders;
using SimpleMap.Setters;

namespace SimpleMap.Extractors
{
   

    /// <summary>
    /// Extracts column to propery data value mappings defaulting to 
    /// the filed name in the datasource matches the property name.
    /// The default behavior name can be adjusted by the use of 
    /// the Ignore or Column Attribute.
    /// </summary>
    public class PropertyBindingExtractor<T> : IValueBindingExtractor<T>
    {


        private IPropertyValueSetterFactory<T> _setterFactory;
        
        public PropertyBindingExtractor(IPropertyValueSetterFactory<T> setterFactory) 
        {
            if (setterFactory == null) 
            {
                throw new ArgumentNullException("setterFActory");
            }

            _setterFactory = setterFactory;
        }


        /// <summary>
        /// Extracts list of IValueBinding values based on properties.
        /// </summary>
        /// <returns></returns>
        public List<IValueBinding<T>> Extract()
        {

            List<IValueBinding<T>> elements = new List<IValueBinding<T>>();

            PropertyInfo[] pInfoArray = typeof(T).GetProperties();

            foreach (PropertyInfo p in pInfoArray)
            {
                object[] attributes = p.GetCustomAttributes(typeof(BindingExtractionAttribute), true);

                bool skip = false;
                string column = p.Name;

                foreach (Attribute a in attributes)
                {
                    if (a is Ignore)
                    {
                        skip = true;
                        break;
                    }

                    if (a is Column) 
                    {
                        column = ((Column)a).Name;
                    }
                }

                
                if (!skip)
                {
                    IValueSetter<T> setter = _setterFactory.CreateSetter(p);
                    IValueBinding<T> binding = new ValueBinding<T>(setter, column);
                    elements.Add(binding);
                }
            }

            return elements;
        }
    }

}
